﻿using SqlSugar;
using SqlSugar.Extensions;
using System.ComponentModel;
using System.Data;
using System.Linq.Expressions;
using Zhao.Common.Helper;
using Zhao.IServer.Management_Arena;
using Zhao.Models.AppletDto;
using Zhao.Models.DTO;
using Zhao.Models.Entity;
using Zhao.Repository.Base;
using Zhao.Repository.UnitOfWork;

namespace Zhao.Service.Management_Arena
{
    /// <summary>
    /// 正式球馆表（已入驻商户）
    ///</summary>
    public class VenuesServer : BaseService<Venues>, IVenuesServer
    {
        private readonly IUnitOfWork _unitOfWork;
        public VenuesServer(IBaseRepository<Venues> baseDal, IUnitOfWork unitOfWork) : base(baseDal, unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public async Task<PageModel<VenueDto>> GetVenuesPage(Expression<Func<Venues, Area, Area, Area, bool>> expressionable, int pageIndex, int pageSize)
        {
            //获取总条数
            RefAsync<int> totalCount = 0;

            var list = await _Client.Queryable<Venues>()
                  .LeftJoin<Area>((a, b) => a.Province == b.Id)// b 是 Province 表别名
                  .LeftJoin<Area>((a, b, c) => a.City == c.Id)// c 是 City 表别名
                  .LeftJoin<Area>((a, b, c, d) => a.Zone == d.Id)// d是 District 表别名
                  .WhereIF(expressionable != null, expressionable)
                  .Select((a, b, c, d) => new VenueDto
                  {
                      VenueId = a.VenueID,
                      VenueName = a.VenueName,
                      Address = $"{b.Name}{c.Name}{d.Name}{a.Address}",
                      Image = a.Images,
                      ContactPhone = a.ContactPhone,
                      Description = a.Description,
                      Status = a.IsDeleted,
                      CreatedAt = a.CreatedAt,
                      UpdatedAt = a.UpdatedAt,
                      OpenTime = a.OpenTime.ToString(),
                      CloseTime = a.CloseTime.ToString(),
                      phone = a.Phone,
                      managerName = a.ManagerName,
                      provinceId = a.Province,
                      cityId = a.City,
                      districtId = a.Zone,
                      rRules = a.ReservationRules,
                      LicenseImage = a.License
                  })
                  .ToPageListAsync(pageIndex, pageSize, totalCount).ConfigureAwait(false);

            int totalPage = (Math.Ceiling(totalCount.ObjToDecimal() / pageSize.ObjToDecimal())).ObjToInt();

            return new PageModel<VenueDto>() { count = totalCount, PageCount = totalPage, PageIndex = pageIndex, PageSize = pageSize, data = list, code = totalCount == 0 ? -1 : 0, msg = totalCount == 0 ? "未查询到任何数据" : "" };
        }

        /// <summary>
        /// 更新场馆银行卡信息
        /// </summary>
        /// <param name="venueId">场馆ID</param>
        /// <param name="dto">银行卡信息传输对象</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult> UpdateVenueBankInfo(Guid venueId, BankInfoDto dto)
        {
            var result = new ApiResult();

            try
            {
                // 开始事务
                _Client.Ado.BeginTran();

                // 执行更新
                var rows = await _Client.Updateable<Venues>()
                    .SetColumns(v => new Venues
                    {
                        CardholderName = dto.Name,
                        BankCard = dto.BankCardaccount,
                        Bank = dto.Bank,
                    })
                    .Where(v => v.VenueID == venueId)
                    .ExecuteCommandAsync();

                // 提交事务
                _Client.Ado.CommitTran();

                result.Success = rows > 0;
                result.Message = rows > 0 ? "银行卡信息更新成功" : "未找到场馆记录";
            }
            catch (Exception ex)
            {
                // 回滚事务并处理异常
                _Client.Ado.RollbackTran();
                result.Success = false;
                result.Message = $"更新操作异常：{ex.Message}";
                // 实际项目建议记录日志
            }

            return result;
        }

        /// <summary>
        /// 更新场馆的钱包密码
        /// </summary>
        /// <param name="venueId">场馆ID</param>
        /// <param name="pwd">新密码</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult> UpdateWithdrawPassword(Guid venueId, string pwd)
        {
            var result = new ApiResult();

            try
            {
                // 开始事务
                _Client.Ado.BeginTran();

                // 执行更新
                var rows = await _Client.Updateable<Venues>()
                    .SetColumns(v => new Venues
                    {
                        WithdrawPassword = pwd,
                    })
                    .Where(v => v.VenueID == venueId)
                    .ExecuteCommandAsync();

                // 提交事务
                _Client.Ado.CommitTran();

                result.Success = rows > 0;
                result.Message = rows > 0 ? "钱包密码更改成功" : "未找到场馆记录";
            }
            catch (Exception ex)
            {
                // 回滚事务并处理异常
                _Client.Ado.RollbackTran();
                result.Success = false;
                result.Message = $"更新操作异常：{ex.Message}";
                // 实际项目建议记录日志
            }

            return result;
        }


        #region 小程序API
        /// <summary>
        /// 获取球馆详细信息（分页）
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">每页大小</param>
        /// <returns>球馆信息分页数据</returns>
        public async Task<PageModel<VenueInfoDto>> GetVenueInfo(Expression<Func<Venues, bool>> expressionable, int pageIndex, int pageSize)
        {
            //获取总条数
            RefAsync<int> totalCount = 0;

            var list = await _Client.Queryable<Venues>()

                .WhereIF(expressionable != null, expressionable)
                .Select((a) => new VenueInfoDto
                {
                    VenueId = a.VenueID,
                    VenueName = a.VenueName,
                    Images = a.Images,
                    OpenTime = a.OpenTime.ToString(),
                    CloseTime = a.CloseTime.ToString(),
                    Address = a.Address,
                    ContactPhone = a.ContactPhone
                })
                .ToPageListAsync(pageIndex, pageSize, totalCount).ConfigureAwait(false);

            int totalPage = (Math.Ceiling(totalCount.ObjToDecimal() / pageSize.ObjToDecimal())).ObjToInt();

            return new PageModel<VenueInfoDto>()
            {
                count = totalCount,
                PageCount = totalPage,
                PageIndex = pageIndex,
                PageSize = pageSize,
                data = list,
                code = totalCount == 0 ? -1 : 0,
                msg = totalCount == 0 ? "未查询到任何数据" : ""
            };
        }

        public async Task<VenuesDetailsInfoDto> GetVenuesById(Expression<Func<Venues, Area, Area, Area, bool>> expressionable)
        {
            var data = await _Client.Queryable<Venues>()
                    .LeftJoin<Area>((a, b) => a.Province == b.Id)// b 是 Province 表别名
                    .LeftJoin<Area>((a, b, c) => a.City == c.Id)// c 是 City 表别名
                    .LeftJoin<Area>((a, b, c, d) => a.Zone == d.Id)// d是 District 表别名
                    .WhereIF(expressionable != null, expressionable)
                    .Select((a, b, c, d) => new VenuesDetailsInfoDto
                    {
                        Guid = a.VenueID,
                        Name = a.VenueName,
                        STime = a.OpenTime,
                        ETime = a.CloseTime,
                        ReservationRules = a.ReservationRules,
                        Description = a.Description,
                        Address = $"{b.Name}{c.Name}{d.Name}{a.Address}",
                        ContactPhone = a.ContactPhone,
                        Image = a.Images,
                        Images = SqlFunc.Subqueryable<VenuesImage>()
                        .Where(x => x.VenueId == a.VenueID).ToList(x => x.Imager)
                    }).FirstAsync().ConfigureAwait(false);

            return data;
        }

        /// <summary>
        /// 球馆账号开通与设置
        /// </summary>
        /// <param name="dto">球馆账号设置信息</param>
        /// <param name="applicationId">申请ID</param>
        /// <returns>操作结果</returns>
        public async Task<ApiResult> SetupVenueAccountAsync(VenueAccountSetupDto dto, int applicationId)
        {
            var result = new ApiResult { Success = false };
            
            try
            {
                // 开始事务
                _Client.Ado.BeginTran();
                
                // 查询球馆信息获取负责人姓名
                var venue = await _Client.Queryable<Venues>()
                    .Where(v => v.VenueID == dto.VenueID)
                    .FirstAsync();
                
                if (venue == null)
                {
                    _Client.Ado.RollbackTran();
                    result.Message = "球馆不存在";
                    return result;
                }
                
                // 验证用户名是否已存在
                if (await _Client.Queryable<Admin>().AnyAsync(a => a.UserName == dto.UserName))
                {
                    _Client.Ado.RollbackTran();
                    result.Message = "管理员用户名已存在";
                    return result;
                }
                
                // 验证邮箱是否已存在
                if (await _Client.Queryable<Admin>().AnyAsync(a => a.Email == dto.Email))
                {
                    _Client.Ado.RollbackTran();
                    result.Message = "管理员邮箱已存在";
                    return result;
                }
                
                // 验证手机号是否已存在
                if (await _Client.Queryable<Admin>().AnyAsync(a => a.Phone == dto.Phone))
                {
                    _Client.Ado.RollbackTran();
                    result.Message = "管理员手机号已存在";
                    return result;
                }
                
                // 更新球馆信息
                var updateVenueSuccess = await _Client.Updateable<Venues>()
                    .SetColumns(v => new Venues
                    {
                        OpenTime = dto.OpenTime,
                        CloseTime = dto.CloseTime,
                        ReservationRules = dto.ReservationRules,
                        //WithdrawPassword = dto.WithdrawPassword, // 前端传入的密码应该已经MD5加密
                        ContactPhone = dto.Phone,
                        UpdatedAt = DateTime.Now,
                    })
                    .Where(v => v.VenueID == dto.VenueID)
                    .ExecuteCommandAsync();
                    
                if (updateVenueSuccess <= 0)
                {
                    _Client.Ado.RollbackTran();
                    result.Message = "账号设置失败，请稍后再试";
                    return result;
                }
                
                // 创建球馆管理员账号
                Admin admin = new Admin
                {
                    UserName = dto.UserName,
                    Password = dto.Password, // 控制器已加密
                    Email = dto.Email,
                    Status = true, // 启用状态
                    Role = (int)Common.EnumEntity.RoleEnum.Merchant, // 球馆管理员角色
                    CateTime = DateTime.Now,
                    Phone = dto.Phone, // 使用球馆联系电话
                    FName = venue.ManagerName, // 使用球馆负责人姓名
                    VenueId = dto.VenueID, // 关联球馆ID
                    IsDelete = false,
                    IamgeUrl = dto.Avatar // 管理员头像
                };
                
                // 添加管理员
                var addAdminSuccess = await _Client.Insertable(admin).ExecuteCommandAsync() > 0;
                
                if (!addAdminSuccess)
                {
                    _Client.Ado.RollbackTran();
                    result.Message = "创建球馆管理员账号失败";
                    return result;
                }
                
                // 更新申请状态为已完成(5)
                var updateApplicationSuccess = await _Client.Updateable<VenueApplications>()
                    .SetColumns(a => new VenueApplications
                    {
                        Status = 5, // 已完成
                        UpdatedAt = DateTime.Now
                    })
                    .Where(a => a.ApplicationID == applicationId)
                    .ExecuteCommandAsync();
                
                if (updateApplicationSuccess <= 0)
                {
                    _Client.Ado.RollbackTran();
                    result.Message = "申请状态更新失败，请稍后再试";
                    return result;
                }
                
                // 提交事务
                _Client.Ado.CommitTran();
                
                result.Success = true;
                result.Message = "球馆账号设置成功，申请流程已完成";
            }
            catch (Exception ex)
            {
                _Client.Ado.RollbackTran();
                result.Message = $"账号设置失败：{ex.Message}";
            }
            
            return result;
        }

        /// <summary>
        /// 获取用户关联的已通过申请记录
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>申请记录列表</returns>
        public async Task<List<VenueApplications>> GetUserApplications(int userId)
        {
            try
            {
                // 查询用户的球馆申请记录（已完成状态）
                var applications = await _Client.Queryable<VenueApplications>()
                    .Where(a => a.CreatedByUserID == userId && a.Status == 5 && a.VenunId != null)
                    .ToListAsync();

                return applications ?? new List<VenueApplications>();
            }
            catch (Exception ex)
            {
                // 记录异常但返回空列表
                return new List<VenueApplications>();
            }
        }
        #endregion
    }
}
